package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tbit.uqbike.object.pojo.ParamDate;
import com.tbit.uqbike.object.pojo.Role;
import com.tbit.uqbike.object.pojo.TestSubClass;
import com.tbit.uqbike.object.pojo.dto.AccountDayStatFinancialDTO;
import com.tbit.uqbike.object.pojo.dto.DownloadAllStatDetailDTO;
import com.tbit.manager.api.dto.OperationalDataDTO;
import com.tbit.uqbike.object.pojo.vo.*;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.common.entity.view.PageResult;
import com.tbit.uqbike.service.base.TokenService;
import com.tbit.uqbike.service.business.*;
import com.tbit.uqbike.webmanager.dao.capital.BadOrderDao;
import com.tbit.uqbike.webmanager.dao.core.AccountDao;
import com.tbit.uqbike.webmanager.dao.stat.AccountDayStatDao;
import com.tbit.uqbike.webmanager.util.BeanUtils;
import com.tbit.uqbike.webmanager.util.DateUtils;
import com.tbit.uqbike.webmanager.util.LogUtil;
import com.tbit.uqbike.webmanager.util.csv.CsvExportUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * 财务总览统计
 *
 * @Author:yanlun
 * @DATE: 2022/11/18
 */
@Service
@Slf4j
public class AccountDayStatFinancialServiceImpl implements AccountDayStatFinancialService {


    @Autowired
    DepositStatService depositStatService;
    @Autowired
    TransactionOrderStatService transactionOrderStatService;
    @Autowired
    AdvanceDepositStatService advanceDepositStatService;
    @Autowired
    RefundLogService refundLogService;
    @Autowired
    PayCardLogService payCardLogService;
    @Autowired
    RideLogDetailsService rideLogDetailsService;

    @Autowired
    ArrearsLogService arrearsLogService;
    @Autowired
    GiftCardStatService giftCardStatService;
    @Autowired
    RechargeGiveStatService rechargeGiveStatService;

    @Autowired
    AccountDayStatDao accountDayStatDao;
    @Autowired
    AccountDao accountDao;
    @Autowired
    BadOrderDao badOrderDao;

    @Autowired
    CsvExportUtils csvExportUtils;
    @Autowired
    DownloadAllStatServiceImpl downloadAllStatService;
    @Autowired
    private AccountDayStatService accountDayStatService;
    @Autowired
    private TokenService tokenService;

    /**
     * 补充数据
     *
     * @param list
     * @param startTime
     * @param endTime
     * @param clz
     * @param <T>
     * @return
     */
    public static <T extends ParamDate> List<T> getDateList(List<T> list, Date startTime, Date endTime, Class clz) {
        /**时间区间*/
        List<String> listDate = DateUtils.findDates(startTime, endTime);
        LogUtil.info("listDate日期区间：" + listDate);

        /**对象时间区间*/
        List<String> voDate = list.stream().map(ParamDate::getDate).collect(Collectors.toList());

        /**缺少日期*/
        List<String> dateAdd = listDate.stream().filter(e -> !voDate.contains(e)).collect(toList());
        //补充数据
        for (int i = dateAdd.size() - 1; i >= 0; i--) {
            String dateForYmd = dateAdd.get(i);
            T t = null;
            try {
                t = (T) clz.newInstance();
            } catch (InstantiationException ex) {
                ex.printStackTrace();
            } catch (IllegalAccessException ex) {
                ex.printStackTrace();
            }
            t.setDate(dateForYmd);
            list.add(t);
        }
        return list;

    }

    public static void main(String[] args) {
        /**子类list*/
        List<TestSubClass> testSubClasses = new LinkedList<>();

        /**子类对象*/
        TestSubClass a = new TestSubClass();
        a.setDate("2023-05-01");
        a.setAccountId(1);
        a.setA(2);
        TestSubClass b = new TestSubClass();
        b.setDate("2023-05-03");
        b.setAccountId(2);
        b.setA(5);

        testSubClasses.add(a);
        testSubClasses.add(b);
        System.out.println("参数" + testSubClasses.toString());

        List<Integer> accountIds = new LinkedList<>();
        accountIds.add(1);
        accountIds.add(2);
        testSubClasses = getDateList(testSubClasses, null, null, TestSubClass.class);

        testSubClasses.stream().sorted(Comparator.comparing(TestSubClass::getDate)).collect(Collectors.toList());
        System.out.println(testSubClasses.toString());

    }

    @Override
    public AccountDayStatMerchantFinancialVo financeMerchantPlatform(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        List<AccountDayStatMerchantFinancialDetailVO> pageList = new ArrayList<>();
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatMerchantFinancialDetailVO.class);
        PageInfo<AccountDayStatMerchantFinancialDetailVO> pageInfo = new PageInfo(pageList);
        List<AccountDayStatMerchantFinancialDetailVO> list = new ArrayList<>();
        list = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatMerchantFinancialDetailVO.class);


        AccountDayStatMerchantFinancialVo accountDayStatMerchantFinancialVo = new AccountDayStatMerchantFinancialVo();
        IncomeExpendDetailVo merchant = new IncomeExpendDetailVo();
        merchant.setIncome(list.stream().map(o -> o.getMerchantIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        merchant.setIncomeCount(list.stream().mapToLong(o -> o.getMerchantIncomeCount()).sum());
        merchant.setExpend(list.stream().map(o -> o.getMerchantExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        merchant.setExpendCount(list.stream().mapToLong(o -> o.getMerchantExpendCount()).sum());
        accountDayStatMerchantFinancialVo.setMerchantIncomeExpendDetail(merchant);

        IncomeExpendDetailVo wx = new IncomeExpendDetailVo();
        wx.setIncome(list.stream().map(o -> o.getWxMerchantIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        wx.setIncomeCount(list.stream().mapToLong(o -> o.getWxMerchantIncomeCount()).sum());
        wx.setExpend(list.stream().map(o -> o.getWxMerchantExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        wx.setExpendCount(list.stream().mapToLong(o -> o.getWxMerchantExpendCount()).sum());
        accountDayStatMerchantFinancialVo.setWxIncomeExpendDetail(wx);

        IncomeExpendDetailVo alipay = new IncomeExpendDetailVo();
        alipay.setIncome(list.stream().map(o -> o.getAlipayMerchantIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        alipay.setIncomeCount(list.stream().mapToLong(o -> o.getAlipayMerchantIncomeCount()).sum());
        alipay.setExpend(list.stream().map(o -> o.getAlipayMerchantExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        alipay.setExpendCount(list.stream().mapToLong(o -> o.getAlipayMerchantExpendCount()).sum());
        accountDayStatMerchantFinancialVo.setAlipayIncomeExpendDetail(alipay);

        IncomeExpendDetailVo adapay = new IncomeExpendDetailVo();
        adapay.setIncome(list.stream().map(o -> o.getAdapayMerchantIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        adapay.setIncomeCount(list.stream().mapToLong(o -> o.getAdapayMerchantIncomeCount()).sum());
        adapay.setExpend(list.stream().map(o -> o.getAdapayMerchantExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        adapay.setExpendCount(list.stream().mapToLong(o -> o.getAdapayMerchantExpendCount()).sum());
        accountDayStatMerchantFinancialVo.setAdapayIncomeExpendDetail(adapay);
        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatMerchantFinancialDetailVO.class);
        PageResult<AccountDayStatMerchantFinancialDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());


        accountDayStatMerchantFinancialVo.setPageList(pageResult);
        return accountDayStatMerchantFinancialVo;
    }

    public void areaNameMapping(List list, Integer brandId, Class clazz) {
        Map<Integer, String> map = getAccountIdNameMap(brandId);
        for (Object item : list) {
            if (clazz.equals(AccountDayStatMerchantFinancialDetailVO.class)) {
                AccountDayStatMerchantFinancialDetailVO vo = (AccountDayStatMerchantFinancialDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatOperateDetailVO.class)) {
                AccountDayStatOperateDetailVO vo = (AccountDayStatOperateDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatBalanceDetailVO.class)) {
                AccountDayStatBalanceDetailVO vo = (AccountDayStatBalanceDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatDepositDetailVO.class)) {
                AccountDayStatDepositDetailVO vo = (AccountDayStatDepositDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatGiftCardDetailVO.class)) {
                AccountDayStatGiftCardDetailVO vo = (AccountDayStatGiftCardDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatFictitiousDetailVO.class)) {
                AccountDayStatFictitiousDetailVO vo = (AccountDayStatFictitiousDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatArrearsDetailVO.class)) {
                AccountDayStatArrearsDetailVO vo = (AccountDayStatArrearsDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatTotalDetailVO.class)) {
                AccountDayStatTotalDetailVO vo = (AccountDayStatTotalDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
            if (clazz.equals(AccountDayStatOtherDetailVO.class)) {
                AccountDayStatOtherDetailVO vo = (AccountDayStatOtherDetailVO) item;
                Integer accountId = vo.getAccountId();
                vo.setAccountName(Integer.valueOf(-1).equals(accountId) ? "未知区域" : map.get(accountId));
            }
        }
    }

    public List selectList(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay, Class clazz) {
        Integer startTimeInt = DateUtils.toYYYYMMDDInt(accountDayStatFinancialDTO.getStartTime());
        Integer endTimeInt = DateUtils.toYYYYMMDDInt(accountDayStatFinancialDTO.getEndTime());
        List list = new ArrayList<>();
        if (!byDay) {
            if (clazz.equals(AccountDayStatMerchantFinancialDetailVO.class)) {
                list = accountDayStatDao.getPlatformMerchantFinancial(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
            }
            if (clazz.equals(AccountDayStatOperateDetailVO.class)) {
                List<AccountDayStatOperateDetailVO> operateFinancial = accountDayStatDao.getOperateFinancial(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                List<Map<String, Object>> machineNos =accountDayStatDao.getMachineNos(endTimeInt, accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                Map<Integer, String> machineNoMap = new HashMap<>();
                for (Map<String, Object> machineNo : machineNos) {
                    Integer accountId = Optional.ofNullable(machineNo.get("accountId"))
                            .map(Object::toString)
                            .map(Integer::valueOf)
                            .orElse(null);

                    if (accountId == null) {
                        continue;
                    }

                    String dataType = Optional.ofNullable(machineNo.get("dataType"))
                            .map(Object::toString)
                            .orElse("");

                    Integer machineCount = 0;
                    Integer putInMachineCount = 0;

                    if ("40".equals(dataType)) {
                        machineCount = Optional.ofNullable(machineNo.get("machineCount"))
                                .map(Object::toString)
                                .map(Integer::valueOf)
                                .orElse(0);
                    } else if ("41".equals(dataType)) {
                        putInMachineCount = Optional.ofNullable(machineNo.get("putInMachineCount"))
                                .map(Object::toString)
                                .map(Integer::valueOf)
                                .orElse(0);
                    }

                    machineNoMap.computeIfAbsent(accountId, k -> "0_0");
                    String[] counts = machineNoMap.get(accountId).split("_");
                    int currentMachineCount = Integer.parseInt(counts[0]);
                    int currentPutInMachineCount = Integer.parseInt(counts[1]);

                    machineNoMap.put(accountId, (currentMachineCount + machineCount) + "_" + (currentPutInMachineCount + putInMachineCount));
                }
                for (AccountDayStatOperateDetailVO vo : operateFinancial) {
                    if (Objects.nonNull(machineNoMap.get(vo.getAccountId()))) {
                        String[] count = machineNoMap.get(vo.getAccountId()).split("_");
                        if (count.length < 2) {
                            continue;
                        }
                        vo.setMachineCount(Long.valueOf(count[0]));
                        vo.setPutInMachineCount(Long.valueOf(count[1]));
                    }
                }
                list = operateFinancial;

            }
            if (clazz.equals(AccountDayStatBalanceDetailVO.class)) {
                list = accountDayStatDao.getBalanceFinancial(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
            }
            if (clazz.equals(AccountDayStatDepositDetailVO.class)) {
                list = accountDayStatDao.getDepositFinancial(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
            }
            if (clazz.equals(AccountDayStatGiftCardDetailVO.class)) {
                list = accountDayStatDao.getGiftCardFinancial(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
            }
            if (clazz.equals(AccountDayStatFictitiousDetailVO.class)) {
                list = accountDayStatDao.getFictitiousFinancial(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
            }
            if (clazz.equals(AccountDayStatArrearsDetailVO.class)) {
                list = accountDayStatDao.getArrearsFinancial(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
            }
            if (clazz.equals(AccountDayStatOtherDetailVO.class)) {
                list = badOrderDao.selectOtherFinancial(accountDayStatFinancialDTO.getStartTime(),
                        accountDayStatFinancialDTO.getEndTime(), accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
            }
        } else {
            if (clazz.equals(AccountDayStatMerchantFinancialDetailVO.class)) {
                list = accountDayStatDao.getPlatformMerchantFinancialByDay(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                LogUtil.info("list按天统计-商户平台收支情况----------------------" + list.toString());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatMerchantFinancialDetailVO.class);
                LogUtil.info("list按天统计-商户平台收支情况----------------------" + list.toString());
                list.stream().sorted(Comparator.comparing(AccountDayStatMerchantFinancialDetailVO::getDate)).collect(Collectors.toList());
            }
            if (clazz.equals(AccountDayStatOperateDetailVO.class)) {
                list = accountDayStatDao.getOperateFinancialByDay(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatOperateDetailVO.class);
                list.stream().sorted(Comparator.comparing(AccountDayStatOperateDetailVO::getDate)).collect(Collectors.toList());
            }
            if (clazz.equals(AccountDayStatBalanceDetailVO.class)) {
                list = accountDayStatDao.getBalanceFinancialByDay(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatBalanceDetailVO.class);
                list.stream().sorted(Comparator.comparing(AccountDayStatBalanceDetailVO::getDate)).collect(Collectors.toList());
            }
            if (clazz.equals(AccountDayStatDepositDetailVO.class)) {
                list = accountDayStatDao.getDepositFinancialByDay(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatDepositDetailVO.class);
                list.stream().sorted(Comparator.comparing(AccountDayStatDepositDetailVO::getDate)).collect(Collectors.toList());
            }
            if (clazz.equals(AccountDayStatGiftCardDetailVO.class)) {
                list = accountDayStatDao.getGiftCardFinancialByDay(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatGiftCardDetailVO.class);
                list.stream().sorted(Comparator.comparing(AccountDayStatGiftCardDetailVO::getDate)).collect(Collectors.toList());
            }
            if (clazz.equals(AccountDayStatFictitiousDetailVO.class)) {
                list = accountDayStatDao.getFictitiousFinancialByDay(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatFictitiousDetailVO.class);
                list.stream().sorted(Comparator.comparing(AccountDayStatFictitiousDetailVO::getDate)).collect(Collectors.toList());
            }
            if (clazz.equals(AccountDayStatArrearsDetailVO.class)) {
                list = accountDayStatDao.getArrearsFinancialByDay(startTimeInt, endTimeInt
                        , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatArrearsDetailVO.class);
                list.stream().sorted(Comparator.comparing(AccountDayStatArrearsDetailVO::getDate)).collect(Collectors.toList());
            }
            if (clazz.equals(AccountDayStatOtherDetailVO.class)) {
                list = badOrderDao.selectOtherFinancialByDay(accountDayStatFinancialDTO.getStartTime(),
                        accountDayStatFinancialDTO.getEndTime(), accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());
                list = getDateList(list, accountDayStatFinancialDTO.getStartTime(), accountDayStatFinancialDTO.getEndTime(), AccountDayStatOtherDetailVO.class);
                list.stream().sorted(Comparator.comparing(AccountDayStatOtherDetailVO::getDate)).collect(Collectors.toList());
            }
        }
        return list;
    }

    @Override
    public AccountDayStatOperateVo operateFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        List<AccountDayStatOperateDetailVO> pageList = new ArrayList<>();
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatOperateDetailVO.class);
        PageInfo<AccountDayStatOperateDetailVO> pageInfo = new PageInfo(pageList);

        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatOperateDetailVO.class);
        List<AccountDayStatOperateDetailVO> accountDayStatOperateDetailVOList = new ArrayList<>();
        accountDayStatOperateDetailVOList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatOperateDetailVO.class);
        AccountDayStatOperateVo accountDayStatOperateVo = new AccountDayStatOperateVo();
        IncomeExpendDetailVo op = new IncomeExpendDetailVo();
        op.setIncome(accountDayStatOperateDetailVOList.stream().map(o -> o.getOpIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        op.setIncomeCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getOpIncomeCount()).sum());
        op.setExpend(accountDayStatOperateDetailVOList.stream().map(o -> o.getOpExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        op.setExpendCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getOpExpendCount()).sum());
        accountDayStatOperateVo.setOpIncomeExpendDetail(op);

        IncomeExpendDetailVo ride = new IncomeExpendDetailVo();
        ride.setIncome(accountDayStatOperateDetailVOList.stream().map(o -> o.getRideIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        ride.setIncomeCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getRideIncomeCount()).sum());
        ride.setExpend(accountDayStatOperateDetailVOList.stream().map(o -> o.getRideExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        ride.setExpendCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getRideExpendCount()).sum());
        accountDayStatOperateVo.setRideIncomeExpendDetail(ride);

        IncomeExpendDetailVo fine = new IncomeExpendDetailVo();
        fine.setIncome(accountDayStatOperateDetailVOList.stream().map(o -> o.getFineIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        fine.setIncomeCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getFineIncomeCount()).sum());
        fine.setExpend(accountDayStatOperateDetailVOList.stream().map(o -> o.getFineExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        fine.setExpendCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getFineExpendCount()).sum());
        accountDayStatOperateVo.setFineIncomeExpendDetail(fine);

        IncomeExpendDetailVo card = new IncomeExpendDetailVo();
        card.setIncome(accountDayStatOperateDetailVOList.stream().map(o -> o.getRideCardIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b))
                .add(accountDayStatOperateDetailVOList.stream().map(o -> o.getVipCardIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(accountDayStatOperateDetailVOList.stream().map(o -> o.getDepositCardIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(accountDayStatOperateDetailVOList.stream().map(o -> o.getCouponCardIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
        );
        card.setIncomeCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getRideCardIncomeCount()).sum() +
                accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getVipCardIncomeCount()).sum() +
                accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getDepositCardIncomeCount()).sum() +
                accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getCouponCardIncomeCount()).sum());

        card.setExpend(accountDayStatOperateDetailVOList.stream().map(o -> o.getRideCardExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b))
                .add(accountDayStatOperateDetailVOList.stream().map(o -> o.getVipCardExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(accountDayStatOperateDetailVOList.stream().map(o -> o.getDepositCardExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(accountDayStatOperateDetailVOList.stream().map(o -> o.getCouponCardExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
        );

        card.setExpendCount(accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getRideCardExpendCount()).sum() +
                accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getVipCardExpendCount()).sum() +
                accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getDepositCardExpendCount()).sum() +
                accountDayStatOperateDetailVOList.stream().mapToLong(o -> o.getCouponCardExpendCount()).sum());
        accountDayStatOperateVo.setCardIncomeExpendDetail(card);
        PageResult<AccountDayStatOperateDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());
        accountDayStatOperateVo.setPageList(pageResult);

        return accountDayStatOperateVo;
    }

    @Override
    public AccountDayStatBalanceVo balanceFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        List<AccountDayStatBalanceDetailVO> pageList = new ArrayList<>();
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatBalanceDetailVO.class);
        PageInfo<AccountDayStatBalanceDetailVO> pageInfo = new PageInfo(pageList);
        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatBalanceDetailVO.class);
        List<AccountDayStatBalanceDetailVO> list = new ArrayList<>();
        list = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatBalanceDetailVO.class);

        AccountDayStatBalanceVo accountDayStatBalanceVo = new AccountDayStatBalanceVo();
        if (!byDay) {
            accountDayStatBalanceVo.setTermStartBalance(list.stream().map(o -> o.getTermStartBalance()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
            accountDayStatBalanceVo.setTermEndBalance(list.stream().map(o -> o.getTermEndBalance()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        } else {
            if (CollectionUtil.isEmpty(list)) {
                accountDayStatBalanceVo.setTermStartBalance(BigDecimal.ZERO);
                accountDayStatBalanceVo.setTermEndBalance(BigDecimal.ZERO);
            } else {
                accountDayStatBalanceVo.setTermStartBalance(list.get(list.size() - 1).getTermStartBalance());
                accountDayStatBalanceVo.setTermEndBalance(list.get(0).getTermEndBalance());
            }
        }
        IncomeExpendDetailVo incomeExpendDetailVo = new IncomeExpendDetailVo();
        incomeExpendDetailVo.setIncome(list.stream().map(o -> o.getUserRecharge()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b))
                .add(list.stream().map(o -> o.getManualRecharge()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(list.stream().map(o -> o.getRideRefund()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
        );
        incomeExpendDetailVo.setIncomeCount(list.stream().mapToLong(o -> o.getUserRechargeCount()).sum() +
                list.stream().mapToLong(o -> o.getManualRechargeCount()).sum() +
                list.stream().mapToLong(o -> o.getRideRefundCount()).sum());
        incomeExpendDetailVo.setExpend(list.stream().map(o -> o.getUserRefund()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b))
                .add(list.stream().map(o -> o.getManualReduce()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(list.stream().map(o -> o.getRideConsume()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
        );
        incomeExpendDetailVo.setExpendCount(list.stream().mapToLong(o -> o.getUserRefundCount()).sum() +
                list.stream().mapToLong(o -> o.getManualReduceCount()).sum() +
                list.stream().mapToLong(o -> o.getRideConsumeCount()).sum());
        accountDayStatBalanceVo.setBalanceIncomeExpendDetail(incomeExpendDetailVo);

        PageResult<AccountDayStatBalanceDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());
        accountDayStatBalanceVo.setPageList(pageResult);
        return accountDayStatBalanceVo;
    }

    @Override
    public AccountDayStatDepositVo depositFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        List<AccountDayStatDepositDetailVO> pageList;
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatDepositDetailVO.class);
        PageInfo<AccountDayStatDepositDetailVO> pageInfo = new PageInfo(pageList);
        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatDepositDetailVO.class);
        List<AccountDayStatDepositDetailVO> list = new ArrayList<>();
        list = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatDepositDetailVO.class);
        PageResult<AccountDayStatDepositDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());
        AccountDayStatDepositVo accountDayStatDepositVo = new AccountDayStatDepositVo();
        accountDayStatDepositVo.setPageList(pageResult);

        if (!byDay) {
            accountDayStatDepositVo.setTermStart(list.stream().map(o -> o.getTermStart()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
            accountDayStatDepositVo.setTermEnd(list.stream().map(o -> o.getTermEnd()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        } else {
            if (CollectionUtil.isEmpty(list)) {
                accountDayStatDepositVo.setTermStart(BigDecimal.ZERO);
                accountDayStatDepositVo.setTermEnd(BigDecimal.ZERO);
            } else {
                accountDayStatDepositVo.setTermStart(list.get(list.size() - 1).getTermStart());
                accountDayStatDepositVo.setTermEnd(list.get(0).getTermEnd());
            }
        }
        IncomeExpendDetailVo incomeExpendDetailVo = new IncomeExpendDetailVo();
        accountDayStatDepositVo.setIncomeExpendDetail(incomeExpendDetailVo);
        incomeExpendDetailVo.setIncome(list.stream().map(o -> o.getIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        incomeExpendDetailVo.setIncomeCount(list.stream().mapToLong(o -> o.getIncomeCount()).sum());
        incomeExpendDetailVo.setExpend(list.stream().map(o -> o.getRefund()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        incomeExpendDetailVo.setExpendCount(list.stream().mapToLong(o -> o.getRefundCount()).sum());

        return accountDayStatDepositVo;
    }

    @Override
    public AccountDayStatOtherVo otherFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        List<AccountDayStatOtherDetailVO> pageList = new ArrayList<>();
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatOtherDetailVO.class);
        PageInfo<AccountDayStatOtherDetailVO> pageInfo = new PageInfo(pageList);
        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatOtherDetailVO.class);

        List<AccountDayStatOtherDetailVO> list = new ArrayList<>();
        list = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatOtherDetailVO.class);

        PageResult<AccountDayStatOtherDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());
        AccountDayStatOtherVo otherVo = new AccountDayStatOtherVo();
        otherVo.setPageList(pageResult);
        IncomeExpendDetailVo vo = new IncomeExpendDetailVo();
        otherVo.setIncomeExpendDetail(vo);

        if (!byDay) {
            otherVo.setTermStart(list.stream().map(o -> o.getTermStart()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
            otherVo.setTermEnd(list.stream().map(o -> o.getTermEnd()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        } else {
            if (CollectionUtil.isEmpty(list)) {
                otherVo.setTermStart(BigDecimal.ZERO);
                otherVo.setTermEnd(BigDecimal.ZERO);
            } else {
                otherVo.setTermStart(list.get(list.size() - 1).getTermStart());
                otherVo.setTermEnd(list.get(0).getTermEnd());
            }
        }
        vo.setIncome(list.stream().map(o -> o.getIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        vo.setIncomeCount(list.stream().mapToLong(o -> o.getIncomeCount()).sum());
        vo.setExpend(list.stream().map(o -> o.getExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        vo.setExpendCount(list.stream().mapToLong(o -> o.getExpendCount()).sum());

        return otherVo;
    }

    @Override
    public AccountDayStatGiftCardVO giftCardFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());

        List<AccountDayStatGiftCardDetailVO> pageList = new ArrayList<>();
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatGiftCardDetailVO.class);
        PageInfo<AccountDayStatGiftCardDetailVO> pageInfo = new PageInfo(pageList);
        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatGiftCardDetailVO.class);

        PageResult<AccountDayStatGiftCardDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());

        List<AccountDayStatGiftCardDetailVO> list = new ArrayList<>();
        list = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatGiftCardDetailVO.class);

        AccountDayStatGiftCardVO giftCardVO = new AccountDayStatGiftCardVO();
        giftCardVO.setPageList(pageResult);
        if (!byDay) {
            giftCardVO.setTermStart(list.stream().map(o -> o.getTermStart()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
            giftCardVO.setTermEnd(list.stream().map(o -> o.getTermEnd()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        } else {
            if (CollectionUtil.isEmpty(list)) {
                giftCardVO.setTermStart(BigDecimal.ZERO);
                giftCardVO.setTermEnd(BigDecimal.ZERO);
            } else {
                giftCardVO.setTermStart(list.get(list.size() - 1).getTermStart());
                giftCardVO.setTermEnd(list.get(0).getTermEnd());
            }
        }
        IncomeExpendDetailVo incomeExpendDetailVo = new IncomeExpendDetailVo();
        giftCardVO.setIncomeExpendDetail(incomeExpendDetailVo);
        incomeExpendDetailVo.setIncome(list.stream().map(o -> o.getUserRechargeIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b))
                .add(list.stream().map(o -> o.getManualRechargeIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(list.stream().map(o -> o.getExchangeIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
        );
        incomeExpendDetailVo.setIncomeCount(list.stream().mapToLong(o -> o.getUserRechargeIncomeCount()).sum() +
                list.stream().mapToLong(o -> o.getManualRechargeIncomeCount()).sum() +
                list.stream().mapToLong(o -> o.getExchangeIncomeCount()).sum());
        incomeExpendDetailVo.setExpend(list.stream().map(o -> o.getUserRefundExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b))
                .add(list.stream().map(o -> o.getManualSubtractExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(list.stream().map(o -> o.getRideExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
        );
        incomeExpendDetailVo.setExpendCount(list.stream().mapToLong(o -> o.getUserRefundExpendCount()).sum() +
                list.stream().mapToLong(o -> o.getManualSubtractExpendCount()).sum() +
                list.stream().mapToLong(o -> o.getRideExpendCount()).sum());

        return giftCardVO;
    }

    @Override
    public AccountDayStatFictitiousVo fictitiousFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());

        List<AccountDayStatFictitiousDetailVO> pageList = new ArrayList<>();
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatFictitiousDetailVO.class);
        PageInfo<AccountDayStatFictitiousDetailVO> pageInfo = new PageInfo(pageList);
        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatFictitiousDetailVO.class);

        PageResult<AccountDayStatFictitiousDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());

        List<AccountDayStatFictitiousDetailVO> list = new ArrayList<>();
        list = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatFictitiousDetailVO.class);

        for (AccountDayStatFictitiousDetailVO vo : pageList) {
            vo.setFictitiousIncome(vo.getCardIncome().add(vo.getGiftCardIncome()).add(vo.getManualIncome()).add(vo.getOtherIncome()));
            vo.setFictitiousIncomeCount(vo.getCardIncomeCount() + vo.getGiftCardIncomeCount() + vo.getManualIncomeCount() + vo.getOtherIncomeCount());
            vo.setFictitiousExpend(vo.getCardExpend().add(vo.getGiftCardExpend()).add(vo.getManualExpend()).add(vo.getOtherExpend()));
            vo.setFictitiousExpendCount(vo.getCardExpendCount() + vo.getGiftCardExpendCount() + vo.getManualExpendCount() + vo.getOtherExpendCount());
        }

        for (AccountDayStatFictitiousDetailVO vo : list) {
            vo.setFictitiousIncome(vo.getCardIncome().add(vo.getGiftCardIncome()).add(vo.getManualIncome()).add(vo.getOtherIncome()));
            vo.setFictitiousIncomeCount(vo.getCardIncomeCount() + vo.getGiftCardIncomeCount() + vo.getManualIncomeCount() + vo.getOtherIncomeCount());
            vo.setFictitiousExpend(vo.getCardExpend().add(vo.getGiftCardExpend()).add(vo.getManualExpend()).add(vo.getOtherExpend()));
            vo.setFictitiousExpendCount(vo.getCardExpendCount() + vo.getGiftCardExpendCount() + vo.getManualExpendCount() + vo.getOtherExpendCount());
        }
        AccountDayStatFictitiousVo accountDayStatFictitiousVo = new AccountDayStatFictitiousVo();
        accountDayStatFictitiousVo.setPageList(pageResult);

        IncomeExpendDetailVo fictitious = new IncomeExpendDetailVo();
        IncomeExpendDetailVo card = new IncomeExpendDetailVo();
        IncomeExpendDetailVo giftCard = new IncomeExpendDetailVo();
        IncomeExpendDetailVo manual = new IncomeExpendDetailVo();
        IncomeExpendDetailVo other = new IncomeExpendDetailVo();
        accountDayStatFictitiousVo.setFictitious(fictitious);
        accountDayStatFictitiousVo.setCard(card);
        accountDayStatFictitiousVo.setGiftCard(giftCard);
        accountDayStatFictitiousVo.setManual(manual);
        accountDayStatFictitiousVo.setOther(other);
        fictitious.setIncome(list.stream().map(o -> o.getFictitiousIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        fictitious.setIncomeCount(list.stream().mapToLong(o -> o.getFictitiousIncomeCount()).sum());
        fictitious.setExpend(list.stream().map(o -> o.getFictitiousExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        fictitious.setExpendCount(list.stream().mapToLong(o -> o.getFictitiousExpendCount()).sum());

        card.setIncome(list.stream().map(o -> o.getCardIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        card.setIncomeCount(list.stream().mapToLong(o -> o.getCardIncomeCount()).sum());
        card.setExpend(list.stream().map(o -> o.getCardExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        card.setExpendCount(list.stream().mapToLong(o -> o.getCardExpendCount()).sum());

        giftCard.setIncome(list.stream().map(o -> o.getGiftCardIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        giftCard.setIncomeCount(list.stream().mapToLong(o -> o.getGiftCardIncomeCount()).sum());
        giftCard.setExpend(list.stream().map(o -> o.getGiftCardExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        giftCard.setExpendCount(list.stream().mapToLong(o -> o.getGiftCardExpendCount()).sum());

        manual.setIncome(list.stream().map(o -> o.getManualIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        manual.setIncomeCount(list.stream().mapToLong(o -> o.getManualIncomeCount()).sum());
        manual.setExpend(list.stream().map(o -> o.getManualExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        manual.setExpendCount(list.stream().mapToLong(o -> o.getManualExpendCount()).sum());

        other.setIncome(list.stream().map(o -> o.getOtherIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        other.setIncomeCount(list.stream().mapToLong(o -> o.getOtherIncomeCount()).sum());
        other.setExpend(list.stream().map(o -> o.getOtherExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        other.setExpendCount(list.stream().mapToLong(o -> o.getOtherExpendCount()).sum());
        return accountDayStatFictitiousVo;
    }

    @Override
    public AccountDayStatArrearsVo arrearsFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO, boolean byDay) {
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());

        List<AccountDayStatArrearsDetailVO> pageList = new ArrayList<>();
        pageList = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatArrearsDetailVO.class);
        PageInfo<AccountDayStatArrearsDetailVO> pageInfo = new PageInfo(pageList);
        areaNameMapping(pageList, accountDayStatFinancialDTO.getBrandId(), AccountDayStatArrearsDetailVO.class);

        PageResult<AccountDayStatArrearsDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());

        List<AccountDayStatArrearsDetailVO> list = new ArrayList<>();
        list = selectList(accountDayStatFinancialDTO, byDay, AccountDayStatArrearsDetailVO.class);


        AccountDayStatArrearsVo vo = new AccountDayStatArrearsVo();
        IncomeExpendDetailVo arrears = new IncomeExpendDetailVo();
        vo.setArrears(arrears);
        if (!byDay) {
            vo.setTermStart(list.stream().map(o -> o.getTermStart()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
            vo.setTermEnd(list.stream().map(o -> o.getTermEnd()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        } else {
            if (CollectionUtil.isEmpty(list)) {
                vo.setTermStart(BigDecimal.ZERO);
                vo.setTermEnd(BigDecimal.ZERO);
            } else {
                vo.setTermStart(list.get(list.size() - 1).getTermStart());
                vo.setTermEnd(list.get(0).getTermEnd());
            }
        }
        arrears.setIncome(list.stream().map(o -> o.getArrears()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        arrears.setIncomeCount(list.stream().mapToLong(o -> o.getArrearsCount()).sum());
        arrears.setExpend((list.stream().map(o -> o.getArrearsReturn()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)))
                .add(list.stream().map(o -> o.getArrearsFictitiousReturn()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b))));
        arrears.setExpendCount(list.stream().mapToLong(o -> o.getArrearsReturnCount()).sum() + (list.stream().mapToLong(o -> o.getArrearsFictitiousReturnCount()).sum()));
        vo.setPageList(pageResult);
        return vo;
    }

    @Override
    public String downloadTotalFinancial(AccountDayStatFinancialDTO downloadDTO) {
        File tempFile = csvExportUtils.getTempFile();
        try {
            Date startTime = downloadDTO.getStartTime();
            Date endTime = downloadDTO.getEndTime();
            File file = csvExportUtils.export((baseEntity) -> {
                AccountDayStatFinancialDTO dto = BeanUtils.copyProperties(downloadDTO, AccountDayStatFinancialDTO.class);
                dto.setStartTime(baseEntity.getStartTime());
                dto.setEndTime(baseEntity.getEndTime());
                Integer startTimeInt = DateUtils.toYYYYMMDDInt(dto.getStartTime());
                Integer endTimeInt = DateUtils.toYYYYMMDDInt(dto.getEndTime());
                List<AccountDayStatTotalDetailVO> list = accountDayStatDao.getTotalFinancial(startTimeInt, endTimeInt
                        , dto.getAccountIdList(), dto.getBrandId());
                setOtherByDateTime(dto, list);
                areaNameMapping(list, downloadDTO.getBrandId(), AccountDayStatTotalDetailVO.class);
                return list;
            }, AccountDayStatTotalDetailVO.class, startTime, endTime, tempFile, downloadDTO.getFileName());
            String uploadFileName = UUID.randomUUID().toString().replaceAll("-", "");
            return csvExportUtils.uploadZip(tempFile, uploadFileName, file);
        } finally {
            FileUtil.del(tempFile);
        }
    }

    @Override
    public String financialSummaryDownload(AccountDayStatFinancialDTO accountDayStatFinancialDTO) {
        boolean permission = true;
        String token = accountDayStatFinancialDTO.getToken();
        LoginInfo info = tokenService.getLoginInfo(token);
        List<Role> roles = info.getRoles();
        List<String> collect = roles.stream().map(Role::getRoleLevel).collect(Collectors.toList());
        if (!collect.contains("0") && !collect.contains("1")) {
            permission = false;
        }
        File tempFile = csvExportUtils.getTempFile();
        try {
            OperationalDataDTO operationalDataDTO = BeanUtils.copyProperties(accountDayStatFinancialDTO, OperationalDataDTO.class);
            Map<String, Object> map = accountDayStatService.operationalData(operationalDataDTO);
            AccountDayStatDownloadAllMerchantVO vo1 = JSON.parseObject(JSON.toJSONString(map), AccountDayStatDownloadAllMerchantVO.class);
            List<AccountDayStatDownloadAllMerchantVO> list1 = new ArrayList<>();
            list1.add(vo1);

            AccountDayStatDownloadAllOperateVO vo2 = JSON.parseObject(JSON.toJSONString(map), AccountDayStatDownloadAllOperateVO.class);
            List<AccountDayStatDownloadAllOperateVO> list2 = new ArrayList<>();
            list2.add(vo2);

            AccountDayStatDownloadAllBalanceVO vo3 = JSON.parseObject(JSON.toJSONString(map), AccountDayStatDownloadAllBalanceVO.class);
            vo3.setOpening_and_closing_balance_start(new BigDecimal(((Map<String, Object>) map.get("startDataMap")).get("opening_and_closing_balance_sum").toString()));
            vo3.setOpening_and_closing_balance_end(new BigDecimal(((Map<String, Object>) map.get("endDataMap")).get("opening_and_closing_balance_sum").toString()));
            List<AccountDayStatDownloadAllBalanceVO> list3 = new ArrayList<>();
            list3.add(vo3);

            AccountDayStatDownloadAllDepositVO vo4 = JSON.parseObject(JSON.toJSONString(map), AccountDayStatDownloadAllDepositVO.class);
            vo4.setDeposit_at_the_beginning_and_end_of_the_period_start(new BigDecimal(((Map<String, Object>) map.get("startDataMap")).get("deposit_at_the_beginning_and_end_of_the_period_sum").toString()));
            vo4.setDeposit_at_the_beginning_and_end_of_the_period_end(new BigDecimal(((Map<String, Object>) map.get("endDataMap")).get("deposit_at_the_beginning_and_end_of_the_period_sum").toString()));
            List<AccountDayStatDownloadAllDepositVO> list4 = new ArrayList<>();
            list4.add(vo4);

            AccountDayStatDownloadAllOtherVO vo5 = JSON.parseObject(JSON.toJSONString(map.get("otherDataMap")), AccountDayStatDownloadAllOtherVO.class);
            List<AccountDayStatDownloadAllOtherVO> list5 = new ArrayList<>();
            list5.add(vo5);

            AccountDayStatDownloadAllArrearsVO vo6 = JSON.parseObject(JSON.toJSONString(map), AccountDayStatDownloadAllArrearsVO.class);
            vo6.setDebt_at_the_beginning_and_end_of_the_period_start(new BigDecimal(((Map<String, Object>) map.get("startDataMap")).get("debt_at_the_beginning_and_end_of_the_period_sum").toString()));
            vo6.setDebt_at_the_beginning_and_end_of_the_period_end(new BigDecimal(((Map<String, Object>) map.get("endDataMap")).get("debt_at_the_beginning_and_end_of_the_period_sum").toString()));
            List<AccountDayStatDownloadAllArrearsVO> list6 = new ArrayList<>();
            list6.add(vo6);

            AccountDayStatDownloadAllGiftCardVO vo7 = JSON.parseObject(JSON.toJSONString(map), AccountDayStatDownloadAllGiftCardVO.class);
            vo7.setGift_card_at_the_beginning_and_end_of_the_period_start(new BigDecimal(((Map<String, Object>) map.get("startDataMap")).get("gift_card_at_the_beginning_and_end_of_the_period_sum").toString()));
            vo7.setGift_card_at_the_beginning_and_end_of_the_period_end(new BigDecimal(((Map<String, Object>) map.get("endDataMap")).get("gift_card_at_the_beginning_and_end_of_the_period_sum").toString()));
            List<AccountDayStatDownloadAllGiftCardVO> list7 = new ArrayList<>();
            list7.add(vo7);

            AccountDayStatDownloadAllXuNiVO vo8 = JSON.parseObject(JSON.toJSONString(map), AccountDayStatDownloadAllXuNiVO.class);
            List<AccountDayStatDownloadAllXuNiVO> list8 = new ArrayList<>();
            list8.add(vo8);

            File file1 = csvExportUtils.exportCsv(AccountDayStatDownloadAllMerchantVO.class, tempFile, "商户平台", list1);
            File file2 = csvExportUtils.exportCsv(AccountDayStatDownloadAllOperateVO.class, tempFile, "运营营收", list2);
            File file3 = csvExportUtils.exportCsv(AccountDayStatDownloadAllBalanceVO.class, tempFile, "预存款", list3);
            File file4 = csvExportUtils.exportCsv(AccountDayStatDownloadAllDepositVO.class, tempFile, "用户押金", list4);
            File file5 = csvExportUtils.exportCsv(AccountDayStatDownloadAllOtherVO.class, tempFile, "其他收支", list5);
            File file6 = csvExportUtils.exportCsv(AccountDayStatDownloadAllArrearsVO.class, tempFile, "用户欠款", list6);
            File file7 = csvExportUtils.exportCsv(AccountDayStatDownloadAllGiftCardVO.class, tempFile, "礼品卡金额", list7);
            File file8 = csvExportUtils.exportCsv(AccountDayStatDownloadAllXuNiVO.class, tempFile, "用车虚拟金额", list8);
            String uploadFileName = UUID.randomUUID().toString().replaceAll("-", "");
            if (!permission) {
                return csvExportUtils.uploadZip(tempFile, uploadFileName, file2, file3, file4, file6, file7, file8);
            }
            return csvExportUtils.uploadZip(tempFile, uploadFileName, file1, file2, file3, file4, file5, file6, file7, file8);
        } finally {
            FileUtil.del(tempFile);
        }
    }

    private void setOtherByDateTime(AccountDayStatFinancialDTO accountDayStatFinancialDTO, List<AccountDayStatTotalDetailVO> list) {
        for (AccountDayStatTotalDetailVO item : list) {
            Integer brandId = accountDayStatFinancialDTO.getBrandId();
            List<Integer> accountIds = accountDayStatFinancialDTO.getAccountIdList();
            List<AccountDayStatOtherDetailVO> accountDayStatOtherDetailVOS = badOrderDao.selectOtherByDateTime(item.getDate() + " 00:00:00", item.getDate() + " 23:59:59", accountIds, brandId);
            if (CollectionUtil.isEmpty(accountDayStatOtherDetailVOS)) {
                item.setOtherIncome(BigDecimal.ZERO);
                item.setOtherIncomeCount(0L);
                item.setOtherExpend(BigDecimal.ZERO);
                item.setOtherExpendCount(0L);
            } else {
                AccountDayStatOtherDetailVO other = accountDayStatOtherDetailVOS.get(0);
                item.setOtherIncome(other.getIncome());
                item.setOtherIncomeCount(other.getIncomeCount());
                item.setOtherExpend(other.getExpend());
                item.setOtherExpendCount(other.getExpendCount());
            }
        }
    }

    @Override
    public AccountDayStatTotalVO totalFinancial(AccountDayStatFinancialDTO accountDayStatFinancialDTO) {
        PageHelper.startPage(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize());
        Integer startTimeInt = DateUtils.toYYYYMMDDInt(accountDayStatFinancialDTO.getStartTime());
        Integer endTimeInt = DateUtils.toYYYYMMDDInt(accountDayStatFinancialDTO.getEndTime());
        List<AccountDayStatTotalDetailVO> pageList = accountDayStatDao.getTotalFinancial(startTimeInt, endTimeInt
                , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());

        LogUtil.info("pageList按天统计-总账单------------------:" + pageList.toString());
        /**补充数据*/
        pageList = getDateList(pageList, accountDayStatFinancialDTO.getStartTime(),
                accountDayStatFinancialDTO.getEndTime(), AccountDayStatTotalDetailVO.class)
                .stream().sorted(Comparator.comparing(AccountDayStatTotalDetailVO::getDate)).collect(Collectors.toList());
        LogUtil.info("pageList按天统计-总账单=================:" + pageList.toString());

        PageInfo<AccountDayStatTotalDetailVO> pageInfo = new PageInfo(pageList);
        PageResult<AccountDayStatTotalDetailVO> pageResult = new PageResult<>(accountDayStatFinancialDTO.getPageIndex(), accountDayStatFinancialDTO.getPageSize(),
                pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());

        List<AccountDayStatTotalDetailVO> list = accountDayStatDao.getTotalFinancial(startTimeInt, endTimeInt
                , accountDayStatFinancialDTO.getAccountIdList(), accountDayStatFinancialDTO.getBrandId());

        AccountDayStatTotalVO vo = new AccountDayStatTotalVO();
        vo.setPageList(pageResult);
        setOtherByDateTime(accountDayStatFinancialDTO, pageList);
        setOtherByDateTime(accountDayStatFinancialDTO, list);

        IncomeExpendDetailVo merchant = new IncomeExpendDetailVo();
        IncomeExpendDetailVo operate = new IncomeExpendDetailVo();
        IncomeExpendDetailVo balance = new IncomeExpendDetailVo();
        IncomeExpendDetailVo deposit = new IncomeExpendDetailVo();
        IncomeExpendDetailVo other = new IncomeExpendDetailVo();
        vo.setMerchant(merchant);
        vo.setOperate(operate);
        vo.setBalance(balance);
        vo.setDeposit(deposit);
        vo.setOther(other);
        merchant.setIncome(list.stream().map(o -> o.getMerchantIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        merchant.setIncomeCount(list.stream().mapToLong(o -> o.getMerchantIncomeCount()).sum());
        merchant.setExpend(list.stream().map(o -> o.getMerchantExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        merchant.setExpendCount(list.stream().mapToLong(o -> o.getMerchantExpendCount()).sum());

        operate.setIncome(list.stream().map(o -> o.getOpIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        operate.setIncomeCount(list.stream().mapToLong(o -> o.getOpIncomeCount()).sum());
        operate.setExpend(list.stream().map(o -> o.getOpExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        operate.setExpendCount(list.stream().mapToLong(o -> o.getOpExpendCount()).sum());

        balance.setIncome(list.stream().map(o -> o.getBalanceIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        balance.setIncomeCount(list.stream().mapToLong(o -> o.getBalanceIncomeCount()).sum());
        balance.setExpend(list.stream().map(o -> o.getBalanceExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        balance.setExpendCount(list.stream().mapToLong(o -> o.getBalanceExpendCount()).sum());

        deposit.setIncome(list.stream().map(o -> o.getDepositIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        deposit.setIncomeCount(list.stream().mapToLong(o -> o.getDepositIncomeCount()).sum());
        deposit.setExpend(list.stream().map(o -> o.getDepositExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        deposit.setExpendCount(list.stream().mapToLong(o -> o.getDepositExpendCount()).sum());

        other.setIncome(list.stream().map(o -> o.getOtherIncome()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        other.setIncomeCount(list.stream().mapToLong(o -> o.getOtherIncomeCount()).sum());
        other.setExpend(list.stream().map(o -> o.getOtherExpend()).reduce(BigDecimal.ZERO, (a, b) -> a.add(b)));
        other.setExpendCount(list.stream().mapToLong(o -> o.getOtherExpendCount()).sum());

        return vo;
    }

    @Override
    public String lastDataTime(Integer brandId, List<Integer> accountIds) {
        List<Integer> accountIdList = null;
        if (CollectionUtil.isEmpty(accountIds)) {
            Map<Integer, String> accountIdNameMap = getAccountIdNameMap(brandId);
            accountIdList = new ArrayList<>(accountIdNameMap.keySet());
        } else {
            accountIdList = accountIds;
        }
        Date date = accountDayStatDao.selectLatelyDataTime(accountIdList);
        return DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
    }

    public String download(AccountDayStatFinancialDTO downloadDTO, Class clazz, boolean byDay) {
        File tempFile = csvExportUtils.getTempFile();
        try {
//            Date startTime = downloadDTO.getStartTime();
//            Date endTime = downloadDTO.getEndTime();
            boolean flag = false;
            if (AccountDayStatOperateDetailByDayVO.class.equals(clazz)) {
                clazz = AccountDayStatOperateDetailVO.class;
                flag = true;
            }
            List list = selectList(downloadDTO, byDay, clazz);
            areaNameMapping(list, downloadDTO.getBrandId(), clazz);
            if (flag) {
                List newList = new ArrayList<AccountDayStatOperateDetailByDayVO>();
                for (Object o : list) {
                    AccountDayStatOperateDetailByDayVO vo = new AccountDayStatOperateDetailByDayVO();
                    org.springframework.beans.BeanUtils.copyProperties(o, vo);
                    newList.add(vo);
                }
                list = newList;
                clazz = AccountDayStatOperateDetailByDayVO.class;
            }
            File file = csvExportUtils.exportCsv(clazz, tempFile, downloadDTO.getFileName(), list);

//            File file = csvExportUtils.export((baseEntity) -> {
//                AccountDayStatFinancialDTO dto = BeanUtils.copyProperties(downloadDTO, AccountDayStatFinancialDTO.class);
//                dto.setStartTime(baseEntity.getStartTime());
//                dto.setEndTime(baseEntity.getEndTime());
//                List list = selectList(dto, byDay, clazz);
//                areaNameMapping(list, downloadDTO.getBrandId(), clazz);
//                return list;
//            }, clazz,startTime,endTime, tempFile, downloadDTO.getFileName());
            String uploadFileName = UUID.randomUUID().toString().replaceAll("-", "");
            return csvExportUtils.uploadZip(tempFile, uploadFileName, file);
        } finally {
            FileUtil.del(tempFile);
        }
    }

    private Map<Integer, String> getAccountIdNameMap(Integer brandId) {
        List<AreaVO> list = accountDao.getAreaByBrandId(brandId);
        Map<Integer, String> map = new HashMap<>();
        for (AreaVO areaVO : list) {
            map.putIfAbsent(areaVO.getAccountId(), areaVO.getName());
        }
        return map;
    }

    @Override
    public String downloadAllStatDetail(DownloadAllStatDetailDTO downloadDTO) {
        return downloadAllStatService.download(downloadDTO);
    }
}
